function [entropyMap] = mkEntropyMap(dataset, prm)
% Make entropy map dataset using the parameters
% prm.{rangeWin, rangeK, rangeAlpha}

rangeWin = prm.rangeWin;
rangeK = prm.rangeK;
rangeAlpha = prm.rangeAlpha;
choice = prm.alphabetChoice;


choiceNames = { 'kMeans alphabet', 'Permutations by Bag', 'Permutations by Row'}; 

% rangeWin = [1, 2, 3, 4, 5, 6];
% rangeK = [15];
% rangeAlpha =[0.1:0.1:2 ];

entType = 'renyi'; % entropy options: shannon or renyi

N = dataset.noInstances;
M = dataset.xseq.noAttrs;     
K = size(dataset.xseq.val,2); 

user = memory;
memStart = user.MemUsedMATLAB;

%ent is a 4-D array to store the entropy for each case(file/patient)
ent = zeros(length(rangeWin), length(rangeK), length(rangeAlpha), N);

%%% Prepare structure with the entropy Map
entropyMap.name = dataset.name;
entropyMap.noInstances = N;
entropyMap.rangeWin = rangeWin;
entropyMap.rangeK = rangeK;
entropyMap.rangeAlpha = rangeAlpha;
entLabels = cell(size(ent(:,:,:,1)));
for widx = 1:length(rangeWin),
    w = rangeWin(widx);
    for kidx = 1:length(rangeK),
        k = rangeK(kidx);
        for aidx=1:length(rangeAlpha),
            alpha = rangeAlpha(aidx);
            msg = sprintf('%s.W%1d.K%1d.A%.1f', entropyMap.name, w, k, alpha);
            entLabels{widx, kidx, aidx} = msg;
        end;
    end;
end;
entropyMap.labels = entLabels;
entropyMap.map = ent;

X = dataset.xseq.val;
iFirst = dataset.xseq.idxFirst;
iLast = dataset.xseq.idxLast;

user = memory;
fprintf('Memory used :: %.3fMB\n', (user.MemUsedMATLAB - memStart)/2^20);
for widx = 1:length(rangeWin),
    
    w = rangeWin(widx);
    
    fprintf('Making slices for window=%1d\n', w);
    sliceseq = mkSlices(dataset.xseq, w);
    slice = sliceseq.val';
    jFirst = sliceseq.idxFirst;
    jLast = sliceseq.idxLast;
    
    % Construct the alphabet
    for kidx = 1:length(rangeK),
        k = rangeK(kidx);

        choiceNames{1} = sprintf('k[%1d]-Means', k);
        fprintf('\tFind entropy map using [%s] alphabet\n', choiceNames{choice});
        
        [clusterIdx, centroid] = mkSliceAlphabet(sliceseq, k, choice);
        k = size(centroid, 1);
        jFirst = sliceseq.idxFirst;
        jLast = sliceseq.idxLast;
        freq = zeros(k,N);
        bins = 1:k;
                
        for p=1:N,
            if jFirst(p) > 0,
            s = clusterIdx(jFirst(p):jLast(p));
            u = histc(s, bins);
            u = u/sum(u);
            freq(:,p) = reshape(u, k, 1);
            end;
        
            z = freq(:,p);
            z  = z(find(z>0));
            entropy = NaN;
            if length(z) > 0,
                for aidx=1:length(rangeAlpha),
                    alpha = rangeAlpha(aidx);
                    switch entType
                        case 'shannon'
                            entropy = -1 * sum(z .* log(z));
                        case 'renyi'
                            if alpha ~= 1
                                entropy = 1/(1-alpha) * log(sum(z .^ alpha) );
                            else
                                entropy = -1 * sum(z .* log(z));
                            end
                        otherwise
                            error('Entropy type is not correct.');
                    end
                    if ~isfinite(entropy),
                        fprintf('Error :: Entropy is not finite [%g] for ', entropy); fprintf('%f ', z); fprintf('\n');
                        pause;
                    end;
                    ent(widx,kidx,aidx,p) = entropy;
                end;
            end;
        end;
        user = memory;
        fprintf('Memory used :: %.3fMB\n', (user.MemUsedMATLAB - memStart)/2^20);
    end;
    entropyMap.map = ent;
    entropyMap.lastWidx =  widx;
    fname = 'icuEntMapTmp';
    save(fname, 'entropyMap');
end % win_size

entropyMap.map = ent;

% make feature vector out of map
[a,b,c,d] = size(ent);
X = zeros(d, a*b*c);
for i=1:d,
    tmp = ent(:,:,:,i);
    tmp = tmp(:);
    X(i,:) = tmp'; 
end;
entropyMap.attrNames = entropyMap.labels(:);
entropyMap.noAttrs = size(X,2);
entropyMap.val = X;